import fs from 'fs'
import path from 'path'
import { randomUUID } from 'crypto'

interface SessionData {
  appid: string
  extractedUserId: string | null
  saasId: string
  username: string
  createdAt: string
  used: boolean
}

interface SessionStorage {
  sessions: Record<string, SessionData>
}

const SESSIONS_FILE_PATH = path.join(__dirname, '../data/sessions.json')
// 从环境变量读取BASE_URL，如果没有配置则使用默认的生产环境地址
const BASE_URL = process.env.USER_RECHARGE_BASE_URL || 'https://usnstygvo.info'

// 确保数据目录存在
function ensureDataDirectory() {
  const dataDir = path.dirname(SESSIONS_FILE_PATH)
  if (!fs.existsSync(dataDir)) {
    fs.mkdirSync(dataDir, { recursive: true })
  }
}

// 读取会话数据
function readSessions(): SessionStorage {
  ensureDataDirectory()
  
  if (!fs.existsSync(SESSIONS_FILE_PATH)) {
    const initialData: SessionStorage = { sessions: {} }
    fs.writeFileSync(SESSIONS_FILE_PATH, JSON.stringify(initialData, null, 2))
    return initialData
  }
  
  try {
    const data = fs.readFileSync(SESSIONS_FILE_PATH, 'utf-8')
    return JSON.parse(data) as SessionStorage
  } catch (error) {
    console.error('Error reading sessions file:', error)
    return { sessions: {} }
  }
}

// 写入会话数据
function writeSessions(data: SessionStorage): void {
  ensureDataDirectory()
  
  try {
    fs.writeFileSync(SESSIONS_FILE_PATH, JSON.stringify(data, null, 2))
  } catch (error) {
    console.error('Error writing sessions file:', error)
    throw new Error('Failed to save session data')
  }
}

// 从 appid 中提取用户ID
export function extractUserIdFromAppId(appid: string): string | null {
  // 处理格式如 "/start 10312" 的 appid
  const match = appid.match(/\/start\s+(\d+)/)
  if (match && match[1]) {
    return match[1]
  }
  
  // 如果不匹配，尝试提取纯数字
  const numberMatch = appid.match(/(\d+)/)
  if (numberMatch && numberMatch[1]) {
    return numberMatch[1]
  }
  
  // 如果都没有匹配到，返回null
  return null
}

// 生成唯一会话ID
export function generateSessionId(): string {
  return randomUUID().replace(/-/g, '').substring(0, 16)
}

// 生成16位银行卡号
export function generateBankCardNumber(): string {
  let cardNumber = ''
  for (let i = 0; i < 16; i++) {
    cardNumber += Math.floor(Math.random() * 10).toString()
  }
  return cardNumber
}

// 创建新会话并返回URL
export function createRechargeSession(input: {
  appid: string
  saasId: string
  username: string
}): { sessionId: string; url: string; extractedUserId: string | null } {
  const sessionId = generateSessionId()
  const extractedUserId = extractUserIdFromAppId(input.appid)
  
  const sessionData: SessionData = {
    appid: input.appid,
    extractedUserId,
    saasId: input.saasId,
    username: input.username,
    createdAt: new Date().toISOString(),
    used: false
  }
  
  const sessions = readSessions()
  sessions.sessions[sessionId] = sessionData
  writeSessions(sessions)
  
  // 构建充值页面URL
  const url = `${BASE_URL}/user-recharge/${sessionId}?appid=${encodeURIComponent(input.appid)}&saasId=${encodeURIComponent(input.saasId)}&username=${encodeURIComponent(input.username)}`
  
  return {
    sessionId,
    url,
    extractedUserId
  }
}

// 获取会话数据
export function getSessionData(sessionId: string): SessionData | null {
  const sessions = readSessions()
  return sessions.sessions[sessionId] || null
}

// 标记会话为已使用
export function markSessionAsUsed(sessionId: string): boolean {
  const sessions = readSessions()
  
  if (sessions.sessions[sessionId]) {
    sessions.sessions[sessionId].used = true
    writeSessions(sessions)
    return true
  }
  
  return false
}

// 清理过期会话（可选，用于定期清理）
export function cleanupExpiredSessions(maxAgeHours: number = 24): number {
  const sessions = readSessions()
  const cutoffTime = new Date(Date.now() - maxAgeHours * 60 * 60 * 1000)
  
  let cleanedCount = 0
  const newSessions: Record<string, SessionData> = {}
  
  Object.entries(sessions.sessions).forEach(([sessionId, sessionData]) => {
    const createdAt = new Date(sessionData.createdAt)
    if (createdAt > cutoffTime) {
      newSessions[sessionId] = sessionData
    } else {
      cleanedCount++
    }
  })
  
  sessions.sessions = newSessions
  writeSessions(sessions)
  
  return cleanedCount
}